package ee.ut.cs.mc.madp.p2pdivider.task;

import static ee.ut.cs.mc.madp.p2pdivider.BaseDividerActivity.HANDLER_TOAST;
import static ee.ut.cs.mc.madp.p2pdivider.BaseDividerActivity.OP_SEPARATOR;
import static ee.ut.cs.mc.madp.p2pdivider.BaseDividerActivity.SERVERPORT;

import java.io.IOException;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Set;

import org.java_websocket.WebSocket;

import android.net.wifi.p2p.WifiP2pInfo;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import ee.ut.cs.mc.madp.p2pdivider.BaseDividerActivity;
import ee.ut.cs.mc.madp.p2pdivider.Command;
import ee.ut.cs.mc.madp.p2pdivider.networking.DividerClient;
import ee.ut.cs.mc.madp.p2pdivider.networking.DividerServer;

/**
 * This task is instantiated only on app host device
 * 
 * @author Kaarel Jõgeva
 */
public class PropagateIpTask extends AsyncTask<InetAddress, Void, Void> {

    private final Handler handler;
    private final DividerServer server;
    private final WifiP2pInfo info;
    private DividerClient client = null;

    public PropagateIpTask(Handler handler, DividerServer server, WifiP2pInfo info) {
        this.handler = handler;
        this.server = server;
        this.info = info;
    }

    @Override
    protected Void doInBackground(InetAddress... params) {
        if (info.isGroupOwner) { // if we happen to be P2P owner and divider host at the same time
            if (server == null) {
                throw new RuntimeException("ERROR: SERVER WAS NULL FOR P2P GROUP OWNER");
            }
            Set<WebSocket> con = server.connections();
            synchronized (con) {
                for (WebSocket socket : con) { // Notify all active connections that new host is divider host
                    String text = Command.IP.name() + OP_SEPARATOR + server.getNewHostIp();
                    socket.send(text);
                }
            }

            // Although we are properly set up, we must close to wrap the server into DividerhostTask
            try {
                server.stop();
            } catch (IOException e) {

            } catch (InterruptedException e) {

            }
            return null;
        }

        try { // Application host, but not P2P group owner
            URI hostUri = new URI("ws://" + params[0].getHostAddress() + ":" + SERVERPORT);
            client = new DividerClient(handler, hostUri);
            client.connectBlocking();
            client.send(Command.IP_PROPAGATE.name() + OP_SEPARATOR); // Signals the running server that it should send out the actual host IP and close
        } catch (URISyntaxException e) {
            Message.obtain(handler, HANDLER_TOAST, "URI is wrong! " + e.getLocalizedMessage()).sendToTarget();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            if (client != null) {
                client.close();
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        Message.obtain(handler, BaseDividerActivity.HANDLER_START_HOST).sendToTarget();
    }
}